package spider

import (
	"context"
	"encoding/json"
	"fmt"
)

type OKEXFuturesInstrument struct {
	InstrumentId        string `json:"instrument_id"`
	Underlying          string `json:"underlying"`
	BaseCurrency        string `json:"base_currency"`
	QuoteCurrency       string `json:"quote_currency"`
	SettlementCurrency  string `json:"settlement_currency"`
	ContractVal         string `json:"contract_val"`
	Listing             string `json:"listing"`
	Delivery            string `json:"delivery"`
	SizeIncrement       string `json:"size_increment"`
	TickSize            string `json:"tick_size"`
	IsInverse           string `json:"is_inverse"`
	Category            string `json:"category"`
	ContractValCurrency string `json:"contract_val_currency"`
	UnderlyingIndex     string `json:"underlying_index"`
}

type OKEXGetFuturesInstrumentsService struct {
	c *Client
}

func (s *OKEXGetFuturesInstrumentsService) Do(ctx context.Context, opts ...RequestOption) (res []*OKEXFuturesInstrument, err error) {
	r := &request{
		method:   "GET",
		endpoint: "/api/swap/v3/instruments",
	}
	data, err := s.c.callAPI(ctx, r, opts...)
	if err != nil {
		return nil, err
	}
	res = make([]*OKEXFuturesInstrument, 0)
	err = json.Unmarshal(data, &res)
	if err != nil {
		return nil, err
	}
	return res, nil
}

type OKEXFuturesInstrumentsService struct {
	c             *Client
	baseCurrency  string
	quoteCurrency string
	infoName      string
}

func (is *OKEXFuturesInstrumentsService) BaseCurrency(bc string) *OKEXFuturesInstrumentsService {
	is.baseCurrency = bc
	return is
}

func (is *OKEXFuturesInstrumentsService) QuoteCurrency(qc string) *OKEXFuturesInstrumentsService {
	is.quoteCurrency = qc
	return is
}

func (is *OKEXFuturesInstrumentsService) InfoName(in string) *OKEXFuturesInstrumentsService {
	is.infoName = in
	return is
}

func (s *OKEXFuturesInstrumentsService) Do(ctx context.Context, opts ...RequestOption) (data []byte, err error) {
	endpoint := fmt.Sprintf("/api/swap/v3/instruments/%s-%s-SWAP/%s", s.baseCurrency, s.quoteCurrency, s.infoName)
	r := &request{
		method:   "GET",
		endpoint: endpoint,
	}
	data, err = s.c.callAPI(ctx, r, opts...)
	if err != nil {
		return nil, err
	}
	return data, err
}

type OKEXGetFuturesMarkPriceService struct {
	c             *Client
	baseCurrency  string
	quoteCurrency *string
}

func (s *OKEXGetFuturesMarkPriceService) BaseCurrency(v string) *OKEXGetFuturesMarkPriceService {
	s.baseCurrency = v
	return s
}

func (s *OKEXGetFuturesMarkPriceService) QuoteCurrency(v string) *OKEXGetFuturesMarkPriceService {
	s.quoteCurrency = &v
	return s
}

func (s *OKEXGetFuturesMarkPriceService) Do(ctx context.Context, opts ...RequestOption) (res *OKEXFuturesMarkPrice, err error) {
	serv := &OKEXFuturesInstrumentsService{c: s.c}
	serv = serv.BaseCurrency(s.baseCurrency).InfoName("mark_price")
	if s.quoteCurrency != nil {
		serv = serv.QuoteCurrency(*s.quoteCurrency)
	} else {
		serv = serv.QuoteCurrency("USDT")
	}
	data, err := serv.Do(ctx, opts...)
	if err != nil {
		return nil, err
	}
	res = new(OKEXFuturesMarkPrice)
	err = json.Unmarshal(data, res)
	if err != nil {
		return nil, err
	}
	return res, nil
}

type OKEXFuturesMarkPrice struct {
	InstrumentId string `json:"instrument_id"`
	MarkPrice    string `json:"mark_price"`
	Timestamp    string `json:"timestamp"`
}
